﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data.Common;
using MySql.Data.MySqlClient;
using System.Data;

namespace Sofire.Data
{
    /// <summary>
    /// 基于 MySql 查询与交互的操作引擎。
    /// </summary>
    public class MySqlQuery : QueryEngineBase
    {
        /// <summary>
        /// 初始化 <see cref="Sofire.Data.MySqlQuery"/> 的新实例。
        /// </summary>
        /// <param name="connectionString">连接字符串。</param>
        public MySqlQuery(string connectionString)
            : base(QueryEngineProvider.MySql, connectionString) { }

        /// <summary>
        /// 初始化 <see cref="Sofire.Data.MySqlQuery"/> 的新实例。
        /// </summary>
        /// <param name="database">数据库。</param>
        /// <param name="user">登录账户。</param>
        /// <param name="password">登录密码。</param>
        /// <param name="charset">字符集。</param>
        public MySqlQuery(string database, string user, string password, string charset)
            : this("localhost", database, user, password, charset) { }

        /// <summary>
        /// 初始化 <see cref="Sofire.Data.MySqlQuery"/> 的新实例。
        /// </summary>
        /// <param name="dataSource">数据源。</param>
        /// <param name="database">数据库。</param>
        /// <param name="user">登录账户。</param>
        /// <param name="password">登录密码。</param>
        /// <param name="charset">字符集。</param>
        public MySqlQuery(string dataSource, string database, string user, string password,string charset)
            : this(dataSource, 3306, database, user, password, charset) { }

        /// <summary>
        /// 初始化 <see cref="Sofire.Data.MySqlQuery"/> 的新实例。
        /// </summary>
        /// <param name="dataSource">数据源。</param>
        /// <param name="port">数据源端口。</param>
        /// <param name="database">数据库。</param>
        /// <param name="user">登录账户。</param>
        /// <param name="password">登录密码。</param>
        /// <param name="charset">字符集。</param>
        public MySqlQuery(string dataSource, int port, string database, string user, string password,string charset)
            : this(string.Format("DataSource={0};Port={1};Database={2};User={3};Password={4};CharSet={5}"
            , dataSource, port, database, user, password, charset)) { }

        /// <summary>
        /// 创建并返回一个 <see cref="MySql.Data.MySqlClient.MySqlCommandBuilder"/> 查询命令生成器。
        /// </summary>
        /// <returns>返回一个查询命令生成器。</returns>
        public override DbCommandBuilder CreateCommandBuilder()
        {
            return new MySqlCommandBuilder();
        }

        /// <summary>
        /// 创建并返回一个 <see cref="MySql.Data.MySqlClient.MySqlConnection"/> 数据源。
        /// </summary>
        /// <returns>返回一个数据库的连接。</returns>
        public override DbConnection CreateConnection()
        {
            return new MySqlConnection(this.ConnectionString);
        }

        /// <summary>
        /// 创建并返回一个 <see cref="MySql.Data.MySqlClient.MySqlDataAdapter"/> 数据适配器。
        /// </summary>
        /// <param name="command">命令对象。</param>
        /// <returns>返回一个数据适配器。</returns>
        public override DbDataAdapter CreateDataAdapter(DbCommand command)
        {
            return new MySqlDataAdapter(command as MySqlCommand);
        }



        /// <summary>
        /// 描述指定的 <see cref="System.Data.Common.DbParameter"/>。
        /// </summary>
        /// <param name="parameter">一个 <see cref="System.Data.Common.DbParameter"/> 的实例。</param>
        /// <returns>返回参数描述的 <see cref="System.String"/> 值。</returns>
        public override string DescribeParameter(DbParameter parameter)
        {
            var p = parameter as MySqlParameter;
            string desc = p.ParameterName;

            switch(p.Direction)
            {
                case ParameterDirection.InputOutput:
                    desc += " IN OUT";
                    break;
                case ParameterDirection.Output:
                    desc += " OUT";
                    break;
            }
            desc += " " + p.MySqlDbType;
            switch(p.MySqlDbType)
            {
                case MySqlDbType.String:
                case MySqlDbType.VarChar:
                case MySqlDbType.VarString:
                case MySqlDbType.Decimal:
                case MySqlDbType.Double:
                case MySqlDbType.Binary:
                case MySqlDbType.VarBinary:
                case MySqlDbType.Float:
                    desc += "(" + p.Size + ")";
                    break;
            }
            return desc;
        }
    }
}
